global mblur_asm

section .rodata
const: dd 0.2, 0.2, 0.2, 0.2

section .data

section .text
;void mblur_asm    (
	;unsigned char *src,
	;unsigned char *dst,
	;int filas,
	;int cols,
	;int src_row_size,
	;int dst_row_size)

mblur_asm:
;rdi = src
;rsi = dst
;edx = cols 
;ecx = filas
;r8d = src_row_size
;r9d = dst_row_size
push rbp
mov rbp, rsp
push r12
push r13
push r14
push r15
%define i r10
%define j r11
%define cols rdx
%define filas rcx
mov ecx, ecx
mov edx, edx
mov r8d, r8d
mov r9d, r9d
xor i,i
xor j,j
sal cols, 2
pxor xmm15, xmm15		;xmm15 = 0
.CicloFilas:
cmp i, filas
je .Fin
xor j,j
mov r12, rdi			;r12 se guarda el principio de la fila actual de src
mov r13, rsi			;r13 se guarda el principio de la fila actual de dst
.CicloColumnas:
cmp j, cols
je .FinColumnas
add j, 8
cmp j, cols
jge .TercerCaso			;if(j+8>=cols)
sub j, 8
cmp j, 8
jl .SegundoCaso			;if(j<8)
cmp i, 2
jl .PrimerCaso			;if(i<2)
add i, 2
cmp i, filas
jge .CuartoCaso			;if(i+2>=filas)
sub i, 2
;Si no salté por ninguno, proceso normalmente
jmp .Procesar
.PrimerCaso:
add j, 16
cmp j, cols
jl .NoArreglar
mov rdi, r12
mov rsi, r13
add rdi, cols
add rsi, cols
sub rdi, 16
sub rsi, 16
mov j, cols
.NoArreglar:
sub j, 16
movdqu [rsi], xmm15
add rsi, 16
add rdi, 16
add j, 16
jmp .CicloColumnas
.SegundoCaso:
xor j, j			;j = 0
mov rdi, r12
mov rsi, r13
movq [rsi], xmm15
add j, 8
add rdi, 8
add rsi, 8
jmp .CicloColumnas
.TercerCaso:
sub j, 8
mov rdi, r12
mov rsi, r13
add rdi, cols
add rsi, cols
sub rdi, 8
sub rsi, 8
movq [rsi], xmm15
add j, 8
add rdi, 8
add rsi, 8
jmp .CicloColumnas
.CuartoCaso:
sub i, 2
add j, 16
cmp j, cols
jl .NoArreglarDos
mov rdi, r12 
mov rsi, r13 
add rdi, cols
add rsi, cols
sub rdi, 16
sub rsi, 16
mov j, cols
.NoArreglarDos:
sub j, 16
movdqu [rsi], xmm15
add rsi, 16
add rdi, 16
add j, 16
jmp .CicloColumnas
.Procesar:
mov r14, rdi                    ;me guardo el puntero posta a src
movdqu xmm0, [rdi]		;xmm0 tiene los 4 píxeles fuente
movdqu xmm1, xmm0
punpcklbw xmm0, xmm15		;xmm0 = |b0|g0|r0|a0|b1|g1|r1|a1|
punpckhbw xmm1, xmm15		;xmm1 = |b2|g2|r2|a2|b3|g3|r3|a3|
sub rdi, r8
sub rdi, 4
movdqu xmm2, [rdi]
movdqu xmm3, xmm2
punpcklbw xmm2, xmm15
punpckhbw xmm3, xmm15
sub rdi, r8
sub rdi, 4
movdqu xmm4, [rdi]
movdqu xmm5, xmm4
punpcklbw xmm4, xmm15
punpckhbw xmm5, xmm15
mov rdi, r14			;vuelvo el puntero al actual
add rdi, r8
add rdi, 4
movdqu xmm6, [rdi]
movdqu xmm7, xmm6
punpcklbw xmm6, xmm15
punpckhbw xmm7, xmm15
add rdi, r8
add rdi, 4
movdqu xmm8, [rdi]
movdqu xmm9, xmm8
punpcklbw xmm8, xmm15
punpckhbw xmm9, xmm15
mov rdi, r14			;restauro definitivamente el puntero
paddw xmm0, xmm2
paddw xmm4, xmm6
paddw xmm0, xmm4
paddw xmm0, xmm8
paddw xmm1, xmm3
paddw xmm5, xmm7
paddw xmm1, xmm5
paddw xmm1, xmm9
movdqu xmm2, xmm0		;xmm2 tiene una copia de las primeras sumas
movdqu xmm3, xmm1		;xmm3 tiene una copia de las segundas sumas
punpcklwd xmm0, xmm15
punpckhwd xmm2, xmm15
punpcklwd xmm1, xmm15
punpckhwd xmm3, xmm15
cvtdq2ps xmm0, xmm0
cvtdq2ps xmm1, xmm1
cvtdq2ps xmm2, xmm2
cvtdq2ps xmm3, xmm3
movdqu xmm4, [const]
mulps xmm0, xmm4
mulps xmm1, xmm4
mulps xmm2, xmm4
mulps xmm3, xmm4
cvttps2dq xmm0, xmm0
cvttps2dq xmm1, xmm1
cvttps2dq xmm2, xmm2
cvttps2dq xmm3, xmm3
packusdw xmm0, xmm2
packusdw xmm1, xmm3
packuswb xmm0, xmm1
movdqu [rsi], xmm0
add j, 16
add rdi, 16
add rsi, 16
jmp .CicloColumnas
.FinColumnas:
inc i
mov rdi, r12
mov rsi, r13
add rdi, r8
add rsi, r9
jmp .CicloFilas
.Fin:
pop r15
pop r14
pop r13
pop r12
pop rbp
ret
